signature X86_ASSEM_STRUCTS = 
sig
end

signature X86_ASSEM = 
sig
  include X86_ASSEM_STRUCTS
   
  datatype reg = Eax | Ebp | Ebx | Ecx | Edi | Edx | Esi | Esp
  
  type lab = string
  
  datatype etype
    = Int
    | Ptr of etype
    | Str of string
    | Wild

  datatype instr
    = Addr of reg * reg * int
    | Addz of int * reg * int
    | Addm of int * reg * reg * int
    | Subr of reg * reg * int
    | Subz of int * reg * int
    | Subm of int * reg * reg * int
    | Mulr of reg * reg * int
    | Mulz of int * reg * int
    | Mulm of int * reg * reg * int
    | Div of reg * int
    | Cltd of int

    | Movld of int * reg * reg * int
    | Movr of reg * reg * int
    | Movst of reg * int * reg * int
    | Movz of int * reg * etype * int

    | Xchg of reg * reg * int
    | Leab of int * reg * reg * int
    | Leal of lab * reg * int
    | Cmpr of reg * reg * int
    | Cmpz of int * reg * int
    | Pop of reg * int
    | Push of reg * int
    | Leave of int

    | Jg of lab * lab * int
    | Je of lab * lab * int
    | Jge of lab * lab * int
    | Jmp of lab * int
    | Call of lab * lab * int
    | Ret of lab * int

    | Label of string * pprop * int
    | Directive of string
    
    | CallMalloc of etype * int
    | CallFree of int
    
  and aptr
    = Preg of reg  
    | Pstk of int * reg
    | Pmem of int * aptr * pexp
    | Pgmem of int
    | Pid of string
  and pexp 
    = Pvar of aptr
    | PintNum of int
    | Pplus of pexp * pexp
    | Pminus of pexp * pexp
    | Ptimes of pexp * pexp

  and pprop
    = Ptrue
    | Pnot of pprop
    | Pand of pprop * pprop
    | Por of pprop * pprop
    | Pge of pexp * pexp
    | Pgt of pexp * pexp
    | Plt of pexp * pexp
    | Ple of pexp * pexp
    | Peq of pexp * pexp
    | Pne of pexp * pexp
    | Pforall of string * etype * pprop
    | Pex of string * etype * pprop
    | Pi of aptr list list
    | N of aptr list
    | D of aptr list
    | Ptree of pexp
    | Plist of pexp
    | Ppred of string * pprop

  type passert = pprop option
  
  datatype func
    = Func of {decs : (etype * aptr * aptr) list,
               pre : pprop,
               post : pprop,
               name : string,
               instrs : instr list,
               pos : int}
               
  datatype textsec
    = Text1 of {funcs : func list,
                pos : int}
                
  datatype dec
    = Dec of {name : string,
              rept : int,
              tipe : etype,
              value : int,
              pos : int}
    
  datatype datasec
    = Data1 of {datas : dec list,
                pos : int}
  
  datatype funrettype
    = FunRetType of {pairs : (string * etype) list,
                     pos : int}
    
  datatype sdec 
    = Sdec of {name : string,
               fields : (int * etype) list,
               pos : int}
               
  datatype prog
    = Prog of {sdec : sdec option,
               funrettype : funrettype,
               textsec : textsec,
               datasec : datasec,
               pos : int}
end
